﻿using System;
using System.Windows;
using System.Windows.Controls;

namespace Microsoft.Xna.Framework.Audio
{
	/// <summary>
	/// Provides a single playing, paused, or stopped instance of a SoundEffect sound.
	/// </summary>
    public class SoundEffectInstance : IDisposable
    {
        MediaElement _mediaElement;
		SoundState _state;
        RoutedEventHandler _loopMediaEventHandler;

		internal MediaElement MediaElement
		{
			get { return _mediaElement; }
		}

		/// <summary>
		/// Gets or sets the panning for the SoundEffectInstance.
		/// </summary>
		public float Pan
		{
			get { return (float)_mediaElement.Balance; }
			set { _mediaElement.Balance = value; }
		}

		/// <summary>
		/// 
		/// </summary>
		public float Pitch
		{
			get { throw new NotImplementedException(); }
			set { throw new NotImplementedException(); }
		}

		/// <summary>
		/// Gets the current state (playing, paused, or stopped) of the SoundEffectInstance.
		/// </summary>
		public SoundState State
		{
			get { return _state; }
		}

		/// <summary>
		/// Gets or sets the volume of the SoundEffectInstance.
		/// </summary>
		public float Volume
		{
			get { return -1; }
			set { throw new NotImplementedException(); }
		}

		#region Constructor
		internal SoundEffectInstance()
        {
            _mediaElement = new MediaElement();
        }
		#endregion

		#region Private Methods
		void _mediaElement_MediaEnded(object sender, RoutedEventArgs e)
        {
            _mediaElement.Play();
        }
		#endregion

		/// <summary>
		/// Gets a value that indicates whether the object is disposed.
		/// </summary>
		public bool IsDisposed
		{
			get { return _mediaElement == null; }
		}

		/// <summary>
		/// Gets a value that indicates whether looping is enabled for the SoundEffectInstance.
		/// </summary>
		public bool IsLooped
		{
			get { return _loopMediaEventHandler != null; }
			set
			{
				if (value && _loopMediaEventHandler == null)
				{
					_loopMediaEventHandler = new RoutedEventHandler(_mediaElement_MediaEnded);
					_mediaElement.MediaEnded += _loopMediaEventHandler;
				}
				else
				{
					_mediaElement.MediaEnded -= _loopMediaEventHandler;
					_loopMediaEventHandler = null;
				}
			}
		}

		/// <summary>
		/// Applies 3D positioning to the sound using a single listener.
		/// </summary>
		/// <param name="listener">Position of the listener.</param>
		/// <param name="emitter">Position of the emitter.</param>
		public void Apply3D(AudioListener listener, AudioEmitter emitter)
		{
		}

		/// <summary>
		/// Applies 3D position to the sound using multiple listeners.
		/// </summary>
		/// <param name="listeners">Positions of each listener.</param>
		/// <param name="emitter">Position of the emitter.</param>
		public void Apply3D(AudioListener[] listeners, AudioEmitter emitter)
		{
		}

		public void Dispose()
		{
			_mediaElement = null;
		}

		public void Pause()
		{
			_mediaElement.Pause();
			_state = SoundState.Paused;
		}

		public virtual void Play()
		{
			if (_loopMediaEventHandler != null)
				_mediaElement.MediaEnded += _loopMediaEventHandler;

			_mediaElement.Play();
			_state = SoundState.Playing;
		}

        public void Resume()
        {
            _mediaElement.Play();
			_state = SoundState.Playing;
        }

        public void Stop()
        {
            if (_loopMediaEventHandler != null)
                _mediaElement.MediaEnded -= _loopMediaEventHandler;

            _mediaElement.Stop();
			_state = SoundState.Stopped;
        }

		public void Stop(bool immediate)
		{
			Stop();
		}
    }
}
